home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / bloodbro.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  12KB  |  411 lines

  1. /***************************************************************************
  2.  
  3.     Video Hardware for Blood Brothers
  4.  
  5. ***************************************************************************/
  6.  
  7. #include "vidhrdw/generic.h"
  8.  
  9. #define NUM_SPRITES 128
  10.  
  11. unsigned char *textlayoutram;
  12. static unsigned char *dirtybuffer2;
  13. static struct osd_bitmap *tmpbitmap2;
  14. extern unsigned char *dirtybuffer2;
  15. unsigned char *bloodbro_videoram2;
  16. unsigned char *bloodbro_scroll;
  17. static struct sprite_list *sprite_list;
  18.  
  19.  
  20. READ_HANDLER( bloodbro_background_r ){
  21.     return READ_WORD (&videoram[offset]);
  22. }
  23.  
  24. WRITE_HANDLER( bloodbro_background_w ){
  25.     int oldword = READ_WORD(&videoram[offset]);
  26.     int newword = COMBINE_WORD(oldword,data);
  27.     if( oldword != newword ){
  28.         WRITE_WORD(&videoram[offset],newword);
  29.         dirtybuffer[offset/2] = 1;
  30.     }
  31. }
  32.  
  33. READ_HANDLER( bloodbro_foreground_r ){
  34.     return READ_WORD (&bloodbro_videoram2[offset]);
  35. }
  36.  
  37. WRITE_HANDLER( bloodbro_foreground_w ){
  38.     int oldword = READ_WORD(&bloodbro_videoram2[offset]);
  39.     int newword = COMBINE_WORD(oldword,data);
  40.     if( oldword != newword ){
  41.         WRITE_WORD(&bloodbro_videoram2[offset],newword);
  42.         dirtybuffer2[offset/2] = 1;
  43.     }
  44. }
  45.  
  46. /**************************************************************************/
  47.  
  48. void bloodbro_vh_stop(void) {
  49.     if( tmpbitmap ) osd_free_bitmap( tmpbitmap );
  50.     if( tmpbitmap2 ) osd_free_bitmap( tmpbitmap2 );
  51.     free( dirtybuffer2 );
  52.     free( dirtybuffer );
  53. }
  54.  
  55. int bloodbro_vh_start(void) {
  56.     tmpbitmap = osd_new_bitmap(512,256,Machine->scrbitmap->depth);
  57.     dirtybuffer = malloc(32*16);
  58.     tmpbitmap2 = osd_new_bitmap(512,256,Machine->scrbitmap->depth);
  59.     dirtybuffer2 = malloc(32*16);
  60.     sprite_list = sprite_list_create( NUM_SPRITES, SPRITE_LIST_FRONT_TO_BACK );
  61.  
  62.     if( tmpbitmap && tmpbitmap2 && dirtybuffer && dirtybuffer2 ){
  63.         memset( dirtybuffer, 1, 32*16 );
  64.         memset( dirtybuffer2, 1, 32*16 );
  65.         sprite_list->transparent_pen = 0xf;
  66.         sprite_list->max_priority = 1;
  67.         sprite_list->sprite_type = SPRITE_TYPE_STACK;
  68.         return 0;
  69.     }
  70.     bloodbro_vh_stop();
  71.     return 1;
  72. }
  73.  
  74. /**************************************************************************/
  75.  
  76. static void draw_text( struct osd_bitmap *bitmap ){
  77.     const struct rectangle *clip = &Machine->drv->visible_area;
  78.     const UINT16 *source = (const UINT16 *)textlayoutram;
  79.     int sx, sy;
  80.     for( sy=0; sy<32; sy++ ){
  81.         for( sx=0; sx<32; sx++ ){
  82.             UINT16 data = *source++;
  83.  
  84.             drawgfx(bitmap,Machine->gfx[0],
  85.                     data&0xfff, /* tile number */
  86.                     data>>12, /* color */
  87.                     0,0,   /* no flip */
  88.                     8*sx,8*sy,
  89.                     clip,TRANSPARENCY_PEN,0xf);
  90.         }
  91.     }
  92. }
  93.  
  94. static void draw_background( struct osd_bitmap *bitmap ) {
  95.     const struct GfxElement *gfx = Machine->gfx[1];
  96.     const UINT16 *source = (UINT16 *)videoram;
  97.     int offs;
  98.     for( offs=0; offs<32*16; offs++ ){
  99.         if( dirtybuffer[offs] ){
  100.             int sx = 16*(offs%32);
  101.             int sy = 16*(offs/32);
  102.             UINT16 data = source[offs];
  103.             dirtybuffer[offs] = 0;
  104.  
  105.             drawgfx(tmpbitmap,gfx,
  106.                 data&0xfff, /* tile number */
  107.                 (data&0xf000)>>12, /* color */
  108.                 0,0, /* no flip */
  109.                 sx,sy,
  110.                 0,TRANSPARENCY_NONE,0);
  111.         }
  112.     }
  113.     {
  114.         int scrollx = -READ_WORD( &bloodbro_scroll[0x20] ); /** ? **/
  115.         int scrolly = -READ_WORD( &bloodbro_scroll[0x22] ); /** ? **/
  116.  
  117.         copyscrollbitmap(bitmap,tmpbitmap,
  118.             1,&scrollx,1,&scrolly,
  119.             &Machine->drv->visible_area,
  120.               TRANSPARENCY_NONE,0);
  121.     }
  122. }
  123.  
  124. static void draw_foreground( struct osd_bitmap *bitmap ) {
  125.     struct rectangle r;
  126.     const struct GfxElement *gfx = Machine->gfx[2];
  127.     const UINT16 *source = (UINT16 *)bloodbro_videoram2;
  128.     int offs;
  129.     for( offs=0; offs<32*16; offs++ ){
  130.         if( dirtybuffer2[offs] ){
  131.             int sx = 16*(offs%32);
  132.             int sy = 16*(offs/32);
  133.             UINT16 data = source[offs];
  134.             dirtybuffer2[offs] = 0;
  135.  
  136.             /* Necessary to use TRANSPARENCY_PEN here */
  137.             r.min_x = sx; r.max_x = sx+15;
  138.             r.min_y = sy; r.max_y = sy+15;
  139.             fillbitmap(tmpbitmap2,0xf,&r);
  140.             /******************************************/
  141.  
  142.             drawgfx( tmpbitmap2,gfx,
  143.                 data&0xfff, /* tile number */
  144.                 (data&0xf000)>>12, /* color */
  145.                 0,0,
  146.                 sx,sy,
  147.                 0,TRANSPARENCY_PEN,0xf);
  148.         }
  149.     }
  150.     {
  151.         int scrollx = -READ_WORD( &bloodbro_scroll[0x24] );
  152.         int scrolly = -READ_WORD( &bloodbro_scroll[0x26] );
  153.  
  154.         copyscrollbitmap(bitmap,tmpbitmap2,1,&scrollx,1,&scrolly,&Machine->drv->visible_area,
  155.                 TRANSPARENCY_PEN,0xf );
  156.     }
  157. }
  158.  
  159. /* SPRITE INFO (8 bytes)
  160.  
  161.    --F???SS SSSSCCCC
  162.    ---TTTTT TTTTTTTT
  163.    -------X XXXXXXXX
  164.    -------- YYYYYYYY */
  165. static void get_sprite_info( void ){
  166.     const struct GfxElement *gfx = Machine->gfx[3];
  167.     const unsigned short *source = (const UINT16 *)spriteram;
  168.     struct sprite *sprite = sprite_list->sprite;
  169.     int count = NUM_SPRITES;
  170.  
  171.     int attributes, flags, number, color, vertical_size, horizontal_size, i;
  172.     while( count-- ){
  173.         attributes = source[0];
  174.         flags = 0;
  175.         if( (attributes&0x8000)==0 ){
  176.             flags |= SPRITE_VISIBLE;
  177.             horizontal_size = 1 + ((attributes>>7)&7);
  178.             vertical_size = 1 + ((attributes>>4)&7);
  179.             sprite->priority = (attributes>>11)&1;
  180.             number = source[1]&0x1fff;
  181.             sprite->x = source[2]&0x1ff;
  182.             sprite->y = source[3]&0x1ff;
  183.  
  184.             /* wraparound - could be handled by Sprite Manager?*/
  185.             if( sprite->x >= 256) sprite->x -= 512;
  186.             if( sprite->y >= 256) sprite->y -= 512;
  187.  
  188.             sprite->total_width = 16*horizontal_size;
  189.             sprite->total_height = 16*vertical_size;
  190.  
  191.             sprite->tile_width = 16;
  192.             sprite->tile_height = 16;
  193.             sprite->line_offset = 16;
  194.  
  195.             if( attributes&0x2000 ) flags |= SPRITE_FLIPX;
  196.             if( attributes&0x4000 ) flags |= SPRITE_FLIPY; /* ? */
  197.             color = attributes&0xf;
  198.  
  199.             sprite->pen_data = gfx->gfxdata + number * gfx->char_modulo;
  200.             sprite->pal_data = &gfx->colortable[gfx->color_granularity * color];
  201.  
  202.             sprite->pen_usage = 0;
  203.             for( i=0; i<vertical_size*horizontal_size; i++ ){
  204.                 sprite->pen_usage |= gfx->pen_usage[number++];
  205.             }
  206.         }
  207.         sprite->flags = flags;
  208.  
  209.         sprite++;
  210.         source+=4;
  211.     }
  212. }
  213.  
  214. static void bloodbro_mark_used_colors(void){
  215.     int offs,i;
  216.     int code, color, colmask[0x80];
  217.     int pal_base = Machine->drv->gfxdecodeinfo[0].color_codes_start;
  218.  
  219.     /* Build the dynamic palette */
  220.     palette_init_used_colors();
  221.  
  222.     /* Text layer */
  223.     pal_base = Machine->drv->gfxdecodeinfo[0].color_codes_start;
  224.     for (color = 0;color < 16;color++) colmask[color] = 0;
  225.     for (offs = 0;offs <0x800;offs += 2) {
  226.         code = READ_WORD(&textlayoutram[offs]);
  227.         color=code>>12;
  228.         if ((code&0xfff)==0xd) continue;
  229.         colmask[color] |= Machine->gfx[0]->pen_usage[code&0xfff];
  230.     }
  231.     for (color = 0;color < 16;color++)
  232.     {
  233.         for (i = 0;i < 15;i++)
  234.         {
  235.             if (colmask[color] & (1 << i))
  236.                 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
  237.         }
  238.     }
  239.  
  240.     /* Tiles - bottom layer */
  241.     pal_base = Machine->drv->gfxdecodeinfo[1].color_codes_start;
  242.     for (offs=0; offs<256; offs++)
  243.         palette_used_colors[pal_base + offs] = PALETTE_COLOR_USED;
  244.  
  245.     /* Tiles - top layer */
  246.     pal_base = Machine->drv->gfxdecodeinfo[2].color_codes_start;
  247.     for (color = 0;color < 16;color++) colmask[color] = 0;
  248.     for (offs = 0x0000;offs <0x400;offs += 2 )
  249.     {
  250.         code = READ_WORD(&bloodbro_videoram2[offs]);
  251.         color= code>>12;
  252.         colmask[color] |= Machine->gfx[2]->pen_usage[code&0xfff];
  253.     }
  254.  
  255.     for (color = 0;color < 16;color++){
  256.         for (i = 0;i < 15;i++)
  257.         {
  258.             if (colmask[color] & (1 << i))
  259.                 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
  260.         }
  261.         /* kludge */
  262.         palette_used_colors[pal_base + 16 * color +15] = PALETTE_COLOR_TRANSPARENT;
  263.         palette_change_color(pal_base + 16 * color +15 ,0,0,0);
  264.     }
  265. }
  266.  
  267. void bloodbro_vh_screenrefresh( struct osd_bitmap *bitmap, int fullrefresh ){
  268.     get_sprite_info();
  269.  
  270.     bloodbro_mark_used_colors();
  271.     sprite_update();
  272.  
  273.     if (palette_recalc()) {
  274.         memset(dirtybuffer,1,32*16);
  275.         memset(dirtybuffer2,1,32*16);
  276.     }
  277.  
  278.     draw_background( bitmap );
  279.     sprite_draw( sprite_list, 1 );
  280.     draw_foreground( bitmap );
  281.     sprite_draw( sprite_list, 0 );
  282.     draw_text( bitmap );
  283. }
  284.  
  285. /* SPRITE INFO (8 bytes)
  286.  
  287.    -------- YYYYYYYY
  288.    ---TTTTT TTTTTTTT
  289.    CCCC--F? -?--????  Priority??
  290.    -------X XXXXXXXX
  291. */
  292.  
  293. static void weststry_draw_sprites( struct osd_bitmap *bitmap, int priority) {
  294.     int offs;
  295.     for( offs = 0x800-8; offs > 0; offs-=8 ){
  296.         int data = READ_WORD( &spriteram[offs+4] );
  297.         int data0 = READ_WORD( &spriteram[offs+0] );
  298.         int tile_number = READ_WORD( &spriteram[offs+2] )&0x1fff;
  299.         int sx = READ_WORD( &spriteram[offs+6] )&0xff;
  300.         int sy = 0xf0-(data0&0xff);
  301.         int flipx = (data&0x200)>>9;
  302.         int datax = (READ_WORD( &spriteram[offs+6] )&0x100);
  303.         int color = (data&0xf000)>>12;
  304.  
  305.         /* Remap sprites */
  306.         switch(tile_number&0x1800) {
  307.             case 0x0000: break;
  308.             case 0x0800: tile_number = (tile_number&0x7ff) | 0x1000; break;
  309.             case 0x1000: tile_number = (tile_number&0x7ff) | 0x800; break;
  310.             case 0x1800: break;
  311.         }
  312.  
  313.         if ((!(data0&0x8000)) && (!datax)) {
  314.             drawgfx(bitmap,Machine->gfx[3],
  315.                 tile_number, color, flipx,0,
  316.                 sx,sy,
  317.                 &Machine->drv->visible_area,TRANSPARENCY_PEN,0xf);
  318.         }
  319.     }
  320. }
  321.  
  322. static void weststry_mark_used_colors(void){
  323.     int offs,i;
  324.     int colmask[0x80],code,pal_base,color;
  325.  
  326.      /* Build the dynamic palette */
  327.     palette_init_used_colors();
  328.  
  329.     /* Text layer */
  330.     pal_base = Machine->drv->gfxdecodeinfo[0].color_codes_start;
  331.     for (color = 0;color < 16;color++) colmask[color] = 0;
  332.     for (offs = 0;offs <0x800;offs += 2) {
  333.         code = READ_WORD(&textlayoutram[offs]);
  334.         color=code>>12;
  335.         if ((code&0xfff)==0xd) continue;
  336.         colmask[color] |= Machine->gfx[0]->pen_usage[code&0xfff];
  337.     }
  338.     for (color = 0;color < 16;color++)
  339.     {
  340.         for (i = 0;i < 15;i++)
  341.         {
  342.             if (colmask[color] & (1 << i))
  343.                 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
  344.         }
  345.     }
  346.  
  347.     /* Tiles - bottom layer */
  348.     pal_base = Machine->drv->gfxdecodeinfo[1].color_codes_start;
  349.     for (offs=0; offs<256; offs++)
  350.         palette_used_colors[pal_base + offs] = PALETTE_COLOR_USED;
  351.  
  352.     /* Tiles - top layer */
  353.     pal_base = Machine->drv->gfxdecodeinfo[2].color_codes_start;
  354.     for (color = 0;color < 16;color++) colmask[color] = 0;
  355.     for (offs = 0x0000;offs <0x400;offs += 2 )
  356.     {
  357.         code = READ_WORD(&bloodbro_videoram2[offs]);
  358.         color= code>>12;
  359.         colmask[color] |= Machine->gfx[2]->pen_usage[code&0xfff];
  360.     }
  361.     for (color = 0;color < 16;color++)
  362.     {
  363.         for (i = 0;i < 15;i++)
  364.         {
  365.             if (colmask[color] & (1 << i))
  366.                 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
  367.         }
  368.  
  369.                 /* kludge */
  370.                 palette_used_colors[pal_base + 16 * color +15] = PALETTE_COLOR_TRANSPARENT;
  371.                 palette_change_color(pal_base + 16 * color +15 ,0,0,0);
  372.     }
  373.  
  374.     /* Sprites */
  375.     pal_base = Machine->drv->gfxdecodeinfo[3].color_codes_start;
  376.     for (color = 0;color < 16;color++) colmask[color] = 0;
  377.     for (offs = 0;offs <0x800;offs += 8 )
  378.     {
  379.         color = READ_WORD(&spriteram[offs+4])>>12;
  380.         code = READ_WORD(&spriteram[offs+2])&0x1fff;
  381.                 /* Remap code 0x800 <-> 0x1000 */
  382.                 code = (code&0x7ff) | ((code&0x800)<<1) | ((code&0x1000)>>1);
  383.  
  384.         colmask[color] |= Machine->gfx[3]->pen_usage[code];
  385.     }
  386.     for (color = 0;color < 16;color++)
  387.     {
  388.         for (i = 0;i < 15;i++)
  389.         {
  390.             if (colmask[color] & (1 << i))
  391.                 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
  392.         }
  393.     }
  394.  
  395.     if (palette_recalc()) {
  396.                 memset(dirtybuffer,1,32*16);
  397.                 memset(dirtybuffer2,1,32*16);
  398.     }
  399. }
  400.  
  401. void weststry_vh_screenrefresh( struct osd_bitmap *bitmap, int fullrefresh ){
  402.     weststry_mark_used_colors();
  403.  
  404.     draw_background( bitmap );
  405.     //weststry_draw_sprites(bitmap,0);
  406.     draw_foreground( bitmap );
  407.     weststry_draw_sprites(bitmap,1);
  408.     draw_text( bitmap );
  409. }
  410.  
  411.